Skip to content

feat(Topology/Connected): local (path-)connectedness of products and pi types#41663

Open
korbonits wants to merge 9 commits into
leanprover-community:masterfrom
korbonits:loc-connected-prod
Open

feat(Topology/Connected): local (path-)connectedness of products and pi types#41663
korbonits wants to merge 9 commits into
leanprover-community:masterfrom
korbonits:loc-connected-prod

Conversation

@korbonits

@korbonits korbonits commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Add product and pi instances for LocallyConnectedSpace and LocallyPathConnectedSpace, together with a full characterization of local (path-)connectedness of pi types:

  • Prod.locallyConnectedSpace / Prod.locallyPathConnectedSpace: binary products.
  • Pi.locallyConnectedSpace_of_finite_nonpreconnected / Pi.locallyPathConnectedSpace_of_finite_nonpathconnected: a product of locally (path-)connected spaces is locally (path-)connected provided all but finitely many factors are preconnected (resp. path-connected). The Finite ι and all-factors-preconnected (resp. path-connected) instances are corollaries.
  • Pi.locallyConnectedSpace_iff / Pi.locallyPathConnectedSpace_iff: a product is locally (path-)connected iff it is empty or the above conditions hold.
  • Topology.IsQuotientMap.locallyConnectedSpace: quotients of locally connected spaces are locally connected (used for the forward direction via the projections; the analogous IsQuotientMap.locallyPathConnectedSpace already existed).

Follow-up to #40092.

AI disclosure

  • level: Level 5 / Level 6 in the link shared -- I feel confident about the math but I am still learning Lean itself
  • code: most of the Lean in this PR was drafted by Claude Code (statements, proofs, docstrings).
  • direction and review: I chose the contribution, made the decisions (e.g., PathConnectedSpace for the path-side hypothesis, strengthening the helper to quotient maps, deferring Quot instances), reviewed every line, and wrote all GitHub/Zulip comments.
  • testing: I ran local lake build of files and lake env lean of some test files (uncommitted)

@github-actions github-actions Bot added the new-contributor This PR was made by a contributor with at most 5 merged PRs. Welcome to the community! label Jul 12, 2026
@github-actions

Copy link
Copy Markdown

Welcome new contributor!

Thank you for contributing to Mathlib! If you haven't done so already, please review our contribution guidelines, as well as the style guide and naming conventions. In particular, we kindly remind contributors that we have guidelines regarding the use of AI when making pull requests.

We use a review queue to manage reviews. If your PR does not appear there, it is probably because it is not successfully building (i.e., it doesn't have a green checkmark), has the awaiting-author tag, or another reason described in the Lifecycle of a PR. The review dashboard has a dedicated webpage which shows whether your PR is on the review queue, and (if not), why.

If you haven't already done so, please come to https://leanprover.zulipchat.com/, introduce yourself, and mention your new PR.

Thank you again for joining our community.

@github-actions github-actions Bot added the t-topology Topological spaces, uniform spaces, metric spaces, filters label Jul 12, 2026
@github-actions

github-actions Bot commented Jul 12, 2026

Copy link
Copy Markdown

PR summary 2ab6a13e5d

Import changes for modified files

No significant changes to the import graph

Import changes for all files
Files Import difference

Declarations diff (regex)

+ Pi.locallyConnectedSpace
+ Pi.locallyConnectedSpace_iff
+ Pi.locallyConnectedSpace_of_finite
+ Pi.locallyConnectedSpace_of_finite_nonpreconnected
+ Pi.locallyPathConnectedSpace
+ Pi.locallyPathConnectedSpace_iff
+ Pi.locallyPathConnectedSpace_of_finite
+ Pi.locallyPathConnectedSpace_of_finite_nonpathconnected
+ Prod.locallyConnectedSpace
+ Prod.locallyPathConnectedSpace
+ Topology.IsQuotientMap.locallyConnectedSpace

You can run this locally as follows
## from your `mathlib4` directory:
git clone https://github.com/leanprover-community/mathlib-ci.git ../mathlib-ci

## summary with just the declaration names:
../mathlib-ci/scripts/pr_summary/declarations_diff.sh <optional_commit>

## more verbose report:
../mathlib-ci/scripts/pr_summary/declarations_diff.sh long <optional_commit>

The doc-module for scripts/pr_summary/declarations_diff.sh in the mathlib-ci repository contains some details about this script.

Declarations diff (Lean)

Lean-aware diff — post-build, computed from the Lean environment (commit 2ab6a13).

  • +11 new declarations
  • −0 removed declarations
+Pi.locallyConnectedSpace
+Pi.locallyConnectedSpace_iff
+Pi.locallyConnectedSpace_of_finite
+Pi.locallyConnectedSpace_of_finite_nonpreconnected
+Pi.locallyPathConnectedSpace
+Pi.locallyPathConnectedSpace_iff
+Pi.locallyPathConnectedSpace_of_finite
+Pi.locallyPathConnectedSpace_of_finite_nonpathconnected
+Prod.locallyConnectedSpace
+Prod.locallyPathConnectedSpace
+Topology.IsQuotientMap.locallyConnectedSpace

No changes to strong technical debt.

No changes to weak technical debt.

Current commit 2ab6a13e5d
Reference commit fd1d54bcac

This script lives in the mathlib-ci repository. To run it locally, from your mathlib4 directory:

git clone https://github.com/leanprover-community/mathlib-ci.git ../mathlib-ci
../mathlib-ci/scripts/reporting/technical-debt-metrics.sh pr_summary
  • The relative value is the weighted sum of the differences with weight given by the inverse of the current value of the statistic.
  • The absolute value is the relative value divided by the total sum of the inverses of the current values (i.e. the weighted average of the differences).

@korbonits

Copy link
Copy Markdown
Contributor Author

LLM-generated

@github-actions github-actions Bot added the LLM-generated PRs with substantial input from LLMs - review accordingly label Jul 12, 2026
@CoolRmal CoolRmal self-assigned this Jul 14, 2026

@CoolRmal CoolRmal left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think here's a better design. May you first prove the following?

theorem Pi.locallyConnectedSpace_of_finite_nonpreconnected
    [∀ i, TopologicalSpace (X i)] [∀ i, LocallyConnectedSpace (X i)]
    (hfinite : {i | ¬PreconnectedSpace (X i)}.Finite) : LocallyConnectedSpace (∀ i, X i) := sorry

which is saying that if every X i is locally connected and the set of i such that X i is not preconnected is finite, then LocallyConnectedSpace (∀ i, X i). Pi.locallyConnectedSpace_of_finite and Pi.locallyConnectedSpace should then be easy corollaries.

You can then do something similar for locally path connected space.

Comment thread Mathlib/Topology/Connected/LocallyConnected.lean Outdated
@CoolRmal

Copy link
Copy Markdown
Contributor

awaiting-author

@github-actions github-actions Bot added the awaiting-author A reviewer has asked the author a question or requested changes. label Jul 14, 2026
@CoolRmal

CoolRmal commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

And maybe if you want you can also prove the following characterization of locally connectedness of the product: ∀ i, X i is locally connected if either it is empty or every X i is locally connected and {i | ¬PreconnectedSpace (X i)}.Finite. To prove this I think you need to show first that if f : X → Y is open continuous surjective and X is locally connected, then so is Y.

@korbonits korbonits changed the title feat(Topology/Connected): products of locally (path-)connected spaces are locally (path-)connected feat(Topology/Connected): local (path-)connectedness of products and pi types Jul 15, 2026
@korbonits

Copy link
Copy Markdown
Contributor Author

And maybe if you want you can also prove the following characterization of locally connectedness of the product: ∀ i, X i is locally connected if either it is empty or every X i is locally connected and {i | ¬PreconnectedSpace (X i)}.Finite. To prove this I think you need to show first that if f : X → Y is open continuous surjective and X is locally connected, then so is Y.

Is it OK if I do this in a follow-up PR or would you prefer to see it in this PR? I can commit to that as a fast follow. I think the helper lemma deserves its own visibility! Open to your thoughts here :) @CoolRmal

@korbonits
korbonits requested a review from CoolRmal July 15, 2026 06:53
@CoolRmal

Copy link
Copy Markdown
Contributor

I think it is fine to include these lemmas in this single PR, but maybe you can change the PR description a little bit.

@grunweg

grunweg commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Hello from triage! Can you comment on whether you used AI for this project (and if so, label with PR with LLM-generated)? Thanks! (Per mathlib's AI policy, this is not forbidden in principle, but its usage must be disclosed.)

@korbonits

Copy link
Copy Markdown
Contributor Author

@grunweg -- correct! I added the LLM-generated tag after pushing the PR to make sure it was tagged correctly. Let me know if there's anything I can do to provide more transparency about my AI usage.

@grunweg

grunweg commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

@grunweg -- correct! I added the LLM-generated tag after pushing the PR to make sure it was tagged correctly. Let me know if there's anything I can do to provide more transparency about my AI usage.

Thanks. Can you also describe how you used AI in the PR description, below the fold? (This scale has some categories that may be helpful.)

@CoolRmal

Copy link
Copy Markdown
Contributor

You should remove the awaiting author label if you want another round of review.

@korbonits

Copy link
Copy Markdown
Contributor Author

-awaiting-author

@github-actions github-actions Bot removed the awaiting-author A reviewer has asked the author a question or requested changes. label Jul 16, 2026

@CoolRmal CoolRmal left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only give comments for LocallyConnectedSpace, but these should also apply to LocallyPathConnectedSpace.

Comment on lines +154 to +155
/-- The image of a locally connected space under a quotient map (in particular, under an open
continuous surjection) is locally connected. -/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/-- The image of a locally connected space under a quotient map (in particular, under an open
continuous surjection) is locally connected. -/
/-- The image of a locally connected space under a quotient map is locally connected. -/

I think there's no need to mention that an open continuous surjection is a quotient map.

Comment on lines +158 to +168
rw [locallyConnectedSpace_iff_connectedComponentIn_open]
intro F hF y _
rw [← hf.isOpen_preimage, isOpen_iff_mem_nhds]
intro x hx
have hxF : x ∈ f ⁻¹' F := connectedComponentIn_subset F y hx
refine Filter.mem_of_superset
((hF.preimage hf.continuous).connectedComponentIn.mem_nhds (mem_connectedComponentIn hxF))
fun z hz ↦ ?_
rw [mem_preimage, connectedComponentIn_eq hx]
exact connectedComponentIn_mono _ (image_preimage_subset f F)
(hf.continuous.mapsTo_connectedComponentIn hxF hz)

@CoolRmal CoolRmal Jul 19, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This long proof suggests that we are missing some APIs. Here's a potentially better way to do this:

  1. Prove this formula for the preimage of a connected component : f ⁻¹' connectedComponentIn F y = ⋃ x ∈ f ⁻¹' connectedComponentIn F y, connectedComponentIn (f ⁻¹' F) x.
  2. We want to show that IsOpen (connectedComponentIn F y), and as f is a quotient map it suffices to show that f ⁻¹' connectedComponentIn F y is open, and by the formula above we know that it is open because it is the union of open sets (where openness of connectedComponentIn (f ⁻¹' F) x follows from the [LocallyConnectedSpace α]).
  3. Moreover, from this proof you can see that we can replace IsQuotientMap f with IsCoinducing f (surjection is not needed; see Topology.isQuotientMap_iff).

Comment on lines +257 to +258
· haveI := hloc
exact Pi.locallyConnectedSpace_of_finite_nonpreconnected hfin

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
· haveI := hloc
exact Pi.locallyConnectedSpace_of_finite_nonpreconnected hfin
· exact locallyConnectedSpace_of_finite_nonpreconnected hfin

rw [nhds_pi, Filter.mem_pi] at hU
obtain ⟨J, hJ, t, ht, htU⟩ := hU
classical
set K := J ∪ {i | ¬PreconnectedSpace (X i)} with hK

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
set K := J ∪ {i | ¬PreconnectedSpace (X i)} with hK
let K := J ∪ {i | ¬PreconnectedSpace (X i)}

And then hK is not needed. As K is not really used a lot of times I think it also makes sense to replace K with J ∪ {i | ¬PreconnectedSpace (X i)} in the proof, but this is optional.

Comment on lines +197 to +198
rw [locallyConnectedSpace_iff_connected_subsets]
intro x U hU

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
rw [locallyConnectedSpace_iff_connected_subsets]
intro x U hU
refine locallyConnectedSpace_iff_connected_subsets.2 fun x U hU ↦ ?_

More concise

refine ⟨K.pi fun i ↦ connectedComponentIn (t i) (x i),
set_pi_mem_nhds (hJ.union hfinite) fun i _ ↦ connectedComponentIn_mem_nhds (ht i), ?_,
fun f hf ↦ htU fun i hiJ ↦ connectedComponentIn_subset _ _ (hf i (mem_union_left _ hiJ))⟩
rw [← univ_pi_piecewise_univ]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May you move classical just before this line (as this is the lemma that uses classical)?

Comment on lines +249 to +250
suffices himg : Function.eval i '' connectedComponent x = univ by
exact ⟨himg ▸ isPreconnected_connectedComponent.image _ (continuous_apply i).continuousOn⟩

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
suffices himg : Function.eval i '' connectedComponent x = univ by
exact ⟨himg ▸ isPreconnected_connectedComponent.image _ (continuous_apply i).continuousOn⟩
suffices himg : Function.eval i '' connectedComponent x = univ from
⟨himg ▸ isPreconnected_connectedComponent.image _ (continuous_apply i).continuousOn⟩

by exact is not preferred.

Comment on lines +251 to +252
refine (subset_univ _).antisymm fun z _ ↦
⟨Function.update x i z, htV fun j hj ↦ ?_, by simp⟩

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
refine (subset_univ _).antisymm fun z _ ↦
⟨Function.update x i z, htV fun j hj ↦ ?_, by simp⟩
refine (subset_univ _).antisymm fun z _ ↦ ⟨Function.update x i z, htV fun j hj ↦ ?_, by simp⟩

No need for a line break like this.

@CoolRmal

Copy link
Copy Markdown
Contributor

awaiting-author

@github-actions github-actions Bot added the awaiting-author A reviewer has asked the author a question or requested changes. label Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-author A reviewer has asked the author a question or requested changes. LLM-generated PRs with substantial input from LLMs - review accordingly new-contributor This PR was made by a contributor with at most 5 merged PRs. Welcome to the community! t-topology Topological spaces, uniform spaces, metric spaces, filters

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants